package com.chuangjiangx.member.score.ddd.domain.model;

import com.chuangjiangx.commons.exception.BaseException;
import com.chuangjiangx.dddbase.Entity;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrScoreGiftRuleId;
import com.chuangjiangx.member.basic.ddd.domain.model.MerchantId;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreGiftRuleScope;
import com.chuangjiangx.domain.shared.model.Enable;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * 积分兑换规则
 * Created by YangKuo on 2018/1/23.
 */
@Getter
public class MbrScoreGiftRule extends Entity<MbrScoreGiftRuleId> {

    /**
     * 兑换规则名称
     */
    private String name;

    /**
     * 兑换条件
     */
    private Long score;

    /**
     * 商品名称
     */
    private String goodsName;
    /**
     * 商品价格
     */
    private BigDecimal goodsPrice;

    /**
     * 规则对象
     */
    private MbrScoreGiftRuleScope scope;

    /**
     * 是否启用
     */
    private Enable enable;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 商户id
     */
    private MerchantId merchantId;

    /**
     * 图片地址
     */
    private String imageUrl;

    /**
     * 兑换次数
     */
    private Long count;

    /**
     * 每人兑换次数限制
     */
    private Integer exchangeLimit;
    /**
     * 说明
     */
    private String remark;
    /**
     * 商品总可兑换次数
     */
    private Integer totalGiftLimit;

    /**
     * 活动开始时间
     */
    private Date startTime;
    /**
     * 活动结束时间
     */
    private Date endTime;


    /**
     * 数据库持久化构造方法
     *
     * @param mbrScoreGiftRuleId 兑换规则id
     * @param name               兑换规则名称
     * @param score              兑换条件
     * @param goodsName          商品名称
     * @param scope              规则对象
     * @param enable             是否启用
     * @param createTime         创建时间
     * @param updateTime         更新时间
     * @param merchantId         商户id
     * @param imageUrl           图片地址
     * @param count              兑换数量
     */
    public MbrScoreGiftRule(MbrScoreGiftRuleId mbrScoreGiftRuleId, String name, Long score, String goodsName, BigDecimal goodsPrice, MbrScoreGiftRuleScope scope, Enable enable, Date createTime,
                            Date updateTime, MerchantId merchantId, String imageUrl, Long count, Integer exchangeLimit,
                            String remark, Integer totalGiftLimit, Date startTime, Date endTime) {
        setId(mbrScoreGiftRuleId);
        this.name = name;
        this.score = score;
        this.goodsName = goodsName;
        this.goodsPrice = goodsPrice;
        this.scope = scope;
        this.enable = enable;
        this.createTime = createTime;
        this.updateTime = updateTime;
        this.merchantId = merchantId;
        this.imageUrl = imageUrl;
        this.count = count;
        this.exchangeLimit = exchangeLimit;
        this.remark = remark;
        this.totalGiftLimit = totalGiftLimit;

        this.startTime = startTime;
        this.endTime = endTime;
    }

    /**
     * 创建积分兑换规则
     *
     * @param merchantId 商户id
     * @param score      积分
     * @param goodsName  商品名称
     */
    public MbrScoreGiftRule(
            MerchantId merchantId, Long score, String goodsName, BigDecimal goodsPrice, String imageUrl, Long count, Integer exchangeLimit,
            String remark, Integer totalGiftLimit,Date startTime, Date endTime) {
        this.merchantId = merchantId;
        this.name = score + "积分兑换商品" + goodsName;
        this.score = score;
        this.goodsName = goodsName;
        this.goodsPrice = goodsPrice;
        this.createTime = new Date();
        this.updateTime = new Date();
        this.scope = MbrScoreGiftRuleScope.ALL;
        this.imageUrl = imageUrl;
        this.count = count == null ? 0L :count;

        this.exchangeLimit = exchangeLimit == null ? Integer.MAX_VALUE : exchangeLimit;
        this.remark = remark;
        this.totalGiftLimit = totalGiftLimit;

        this.startTime = startTime;
        this.endTime = endTime;
        this.enable();
    }

    /**
     * 启用
     */
    public void enable() {
        if (this.enable == null || this.enable != Enable.ENABLE) {
            this.enable = Enable.ENABLE;
        }
    }

    /**
     * 禁用
     */
    public void disable() {
        if (this.enable == null || this.enable != Enable.DISABLE) {
            this.enable = Enable.DISABLE;
        }
    }

    /**
     * 修改积分兑换参数设置
     */
    public void updateModifyScoreGift(
            Long score, String goodsName, BigDecimal goodsPrice, String imageUrl, Long count, Integer exchangeLimit,
            String remark,Integer goodsTotalAmount, Date startTime, Date endTime) {
        this.name = (score == null ? this.score : score) + "积分兑换商品" + StringUtils.defaultIfBlank(goodsName,this.goodsName);
        this.score = score;
        this.goodsName = goodsName;
        this.goodsPrice = goodsPrice;
        this.count = count;
        this.imageUrl = imageUrl;


        this.exchangeLimit = exchangeLimit;
        this.remark = remark;
        this.totalGiftLimit = goodsTotalAmount;
        this.startTime = startTime;
        this.endTime = endTime;
        this.updateTime = new Date();
    }

    /**
     * 提前结束兑换活动
     */
    public void finishActivity() {
        Date now = new Date();
        check();
        this.endTime = now;
        this.updateTime = now;
    }

    public void check() {
        if(!Objects.equals(Enable.ENABLE,this.enable)){
            throw new BaseException("","活动处于禁用状态");
        }
        Date now = new Date();
        if (DateUtils.truncatedCompareTo(this.startTime, now, Calendar.DATE) > 0) {
            throw new BaseException("","活动还未开始");
        }
        if (DateUtils.truncatedCompareTo(this.endTime, now, Calendar.DATE) < 0) {
            throw new BaseException("","活动已结束");
        }
    }

    /**
     * 剩余兑换规则是否可兑换次数
     * @return
     */
    public long remainGiftCount(){
        return  (this.getTotalGiftLimit()-this.getCount());
    }

}
